//------------------------------------------------------------------------------
// Fichiers d'ent�te utilis�s
//------------------------------------------------------------------------------
#include "OutlineContainer.hpp"
#include "Tools/Logger.hpp"

//------------------------------------------------------------------------------
// Définition de constantes
//------------------------------------------------------------------------------
namespace ImageAnalysis
{
	//----------------------------------------------------------------------
	// Constructeur
	//----------------------------------------------------------------------
	OutlineContainer::OutlineContainer( int width, int height ):
	imageWidth(width),
	imageHeight(height)
	{

	}

	//----------------------------------------------------------------------
	// Destructeur
	//----------------------------------------------------------------------
	OutlineContainer::~OutlineContainer( )
	{
		TOutlineContainerIterator iterator;
		for( iterator = outlineList.begin(); iterator != outlineList.end(); ++iterator )
		{
			delete *iterator;
		}
		outlineList.clear();
	}

	//----------------------------------------------------------------------
	//
	//----------------------------------------------------------------------
	int OutlineContainer::GetWidth( )
	{
		return imageWidth;
	}

	//----------------------------------------------------------------------
	//
	//----------------------------------------------------------------------
	int OutlineContainer::GetHeight( )
	{
		return imageHeight;
	}

	//----------------------------------------------------------------------
	//
	//----------------------------------------------------------------------
	int OutlineContainer::GetNumberOfOutline( )
	{
		return outlineList.size();
	}

	//----------------------------------------------------------------------
	// Fusion outline1 avec outline2 et met le r�ultat dans outline1
	// end1WithStart2 : vrai
	//  outline1.end -> outline2.start
	// end1WithStart2 : faux
	//  outline1.end -> outline2.end
	//----------------------------------------------------------------------	
	void OutlineContainer::MergeOutline( Outline* outline1, Outline* outline2 , OutlineContainer::MergeType type )
	//void OutlineContainer::MergeOutline( Outline* outline1, Outline* outline2 , bool end1WithStart2 )
	{
		Outline::TOutlineIterator iterator;
		switch( type )
		{
			case START1_END2:
				// NOT IMPLEMTED
				break;
			case START1_START2:				
				for( iterator = outline2->GetStartIndex(); iterator != outline2->GetEndIndex(); ++iterator )
				{
					outline1->AddIndexBeforeStart( *iterator );
				}
				break;
			case END1_START2:
				for( iterator = outline2->GetStartIndex(); iterator != outline2->GetEndIndex(); ++iterator )
				{
					outline1->AddIndexAfterEnd( *iterator );
				}	
				break;
			case END1_END2:
				for( iterator = --outline2->GetEndIndex(); iterator != outline2->GetStartIndex(); --iterator )
				{
					outline1->AddIndexAfterEnd( *iterator );
				}
				// Cas particulier on ajoute le premier du outline2
				outline1->AddIndexAfterEnd( *outline2->GetStartIndex() );
				break;
			default:
				break;
		}
/*
		if( end1WithStart2 )
		{
			Outline::TOutlineIterator iterator;
			for( iterator = outline2->GetStartIndex(); iterator != outline2->GetEndIndex(); ++iterator )
			{
				outline1->AddIndexAfterEnd( *iterator );
			}
		}
		else
		{
			Outline::TOutlineIterator iterator;
			for( iterator = --outline2->GetEndIndex(); iterator != outline2->GetStartIndex(); --iterator )
			{
				outline1->AddIndexAfterEnd( *iterator );
			}
			// Cas particulier on ajoute le premier du outline2
			outline1->AddIndexAfterEnd( *outline2->GetStartIndex() );
		}*/
	}

	//----------------------------------------------------------------------
	//
	//----------------------------------------------------------------------
	void OutlineContainer::AddOutline( Outline* outline )
	{
		outlineList.push_front( outline );
	}

	//----------------------------------------------------------------------
	//
	//----------------------------------------------------------------------
	void OutlineContainer::LogPrint( )
	{
		TOutlineContainerIterator iterator;

		Tools::ILogger::Log( "Nombre de contour [%d]\n", outlineList.size() );
		for( iterator = outlineList.begin(); iterator != outlineList.end(); ++iterator )
		{
			Outline* outline = *iterator;
			int start = *outline->GetStartIndex();
			int end   = *(--outline->GetEndIndex());
			int size  = outline->GetNumberOfIndex();
			Tools::ILogger::Log( "Contour [start:%d,end:%d,size:%d]\n", start, end, size );
		}
	}

	void OutlineContainer::ImagePrint( RGBImage* image )
	{
		TOutlineContainerIterator iterator;
		//unsigned char value = BinaryImage::WHITE_VALUE;
		unsigned char* value;
		int out = 0;

		for( iterator = outlineList.begin(); iterator != outlineList.end(); ++iterator )
		{
			if( out == 1 )
			{	value = RGBImage::Red; out = 0; }
			else
			{	value = RGBImage::Blue; out = 1; }

			Outline* outline = *iterator;
			Outline::TOutlineIterator iteratorOutline;
			for( iteratorOutline = outline->GetStartIndex(); iteratorOutline != outline->GetEndIndex(); ++iteratorOutline )
			{
				image->SetPixel( *iteratorOutline, value);
			}
		}
	}

	//----------------------------------------------------------------------
	// Méthode
	//----------------------------------------------------------------------
/*
	OutlineContainer::TOulineContainerIterator OutlineContainer::GetStartOutline( )
	{
		return outlineList.begin();
	}

	//----------------------------------------------------------------------
	//
	//----------------------------------------------------------------------
	OutlineContainer::TOulineIterator OutlineContainer::GetEndOutline( )
	{
		return outlineList.end();
	}*/
}

